package cn.turboinfo.fuyang.api.domain.admin.usecase.company;

import cn.turboinfo.fuyang.api.domain.common.service.agencies.AgenciesService;
import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyService;
import cn.turboinfo.fuyang.api.domain.common.service.division.DivisionService;
import cn.turboinfo.fuyang.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.fuyang.api.domain.common.service.role.RoleService;
import cn.turboinfo.fuyang.api.domain.common.service.user.SysUserRoleService;
import cn.turboinfo.fuyang.api.domain.common.service.user.UserProfileService;
import cn.turboinfo.fuyang.api.domain.common.usecase.AbstractUseCase;
import cn.turboinfo.fuyang.api.entity.admin.pojo.role.Role;
import cn.turboinfo.fuyang.api.entity.admin.pojo.user.SysUserRole;
import cn.turboinfo.fuyang.api.entity.common.pojo.agencies.Agencies;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompany;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.QHousekeepingCompany;
import cn.turboinfo.fuyang.api.entity.common.pojo.division.Division;
import cn.turboinfo.fuyang.api.entity.common.pojo.file.FileAttachment;
import cn.turboinfo.fuyang.api.entity.common.pojo.user.UserProfile;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import net.sunshow.toolkit.core.qbean.api.enums.Operator;
import net.sunshow.toolkit.core.qbean.api.request.QFilter;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Component
public class HousekeepingCompanySearchUseCase extends AbstractUseCase<HousekeepingCompanySearchUseCase.InputData, HousekeepingCompanySearchUseCase.OutputData> {
    private final HousekeepingCompanyService housekeepingCompanyService;
    private final FileAttachmentService fileAttachmentService;
    private final DivisionService divisionService;
    private final UserProfileService userProfileService;
    private final AgenciesService agenciesService;
    private final SysUserRoleService sysUserRoleService;
    private final RoleService roleService;

    @Override
    protected OutputData doAction(InputData inputData) {

        QRequest request = inputData.getRequest();

        Long userId = inputData.getUserId();

        UserProfile userProfile = userProfileService.getByIdEnsure(userId);

        Long agenciesId = userProfile.getAgenciesId();

        Set<Long> roleIdSet = sysUserRoleService.findBySysUserId(userId)
                .stream()
                .map(SysUserRole::getRoleId)
                .collect(Collectors.toSet());

        Optional<Role> roleOptional = roleService.findByIdCollection(roleIdSet).stream()
                .filter(it -> it.getCode().equals("admin") || it.getCode().equals("platform"))
                .findAny();

        // 如果是管理员或者平台运营 则不需要过滤
        if (roleOptional.isEmpty() && agenciesId != null && agenciesId > 0) {
            Agencies agencies = agenciesService.getByIdEnsure(agenciesId);
            List<QFilter> filterList = new ArrayList<>();

            {
                QFilter qFilter = new QFilter();
                qFilter.setValue(agencies.getAreaCode());
                qFilter.setOperator(Operator.EQUAL);
                qFilter.setField(QHousekeepingCompany.provinceCode);
                filterList.add(qFilter);
            }
            {
                QFilter qFilter = new QFilter();
                qFilter.setValue(agencies.getAreaCode());
                qFilter.setOperator(Operator.EQUAL);
                qFilter.setField(QHousekeepingCompany.cityCode);
                filterList.add(qFilter);
            }
            {
                QFilter qFilter = new QFilter();
                qFilter.setValue(agencies.getAreaCode());
                qFilter.setOperator(Operator.EQUAL);
                qFilter.setField(QHousekeepingCompany.areaCode);
                filterList.add(qFilter);
            }
            request.filterOr(filterList.toArray(new QFilter[filterList.size()]));
        }


        QResponse<HousekeepingCompany> response = housekeepingCompanyService.findAll(inputData.request, inputData.getRequestPage());

        List<HousekeepingCompany> companyList = new ArrayList<>(response.getPagedData());

        // 地区编码
        List<Long> divisionIdList = new ArrayList<>();
        //附件
        Set<Long> companyIdList = new HashSet<>();

        companyList.forEach(company -> {
            divisionIdList.add(company.getProvinceCode());
            divisionIdList.add(company.getCityCode());
            divisionIdList.add(company.getAreaCode());
            companyIdList.add(company.getId());
        });

        Map<Long, Division> divisionMap = divisionService.findByIdCollection(divisionIdList)
                .stream()
                .collect(Collectors.toMap(Division::getId, Function.identity()));

        val companyAttachMap = fileAttachmentService.findByRefIdInAndRefType(companyIdList, "companyAttach").stream()
                .collect(Collectors.toMap(FileAttachment::getId, Function.identity()));

        companyList
                .stream()
                .forEach(company -> {
                    // 不返回 appId、 appSecret
                    company.setAppId(null);
                    company.setAppSecret(null);
                    if (company.getProvinceCode() != null && divisionMap.containsKey(company.getProvinceCode())) {
                        company.setProvinceName(divisionMap.get(company.getProvinceCode()).getAreaName());
                    }

                    if (company.getCityCode() != null && divisionMap.containsKey(company.getCityCode())) {
                        company.setCityName(divisionMap.get(company.getCityCode()).getAreaName());
                    }

                    if (company.getAreaCode() != null && divisionMap.containsKey(company.getAreaCode())) {
                        company.setAreaName(divisionMap.get(company.getAreaCode()).getAreaName());
                    }

                    if (companyAttachMap.containsKey(company.getBusinessLicenseFile())) {
                        company.setBusinessLicenseFileName(companyAttachMap.get(company.getBusinessLicenseFile()).getDisplayName());
                    }
                    if (companyAttachMap.containsKey(company.getLegalPersonIdCardFile())) {
                        company.setLegalPersonIdCardFileName(companyAttachMap.get(company.getLegalPersonIdCardFile()).getDisplayName());
                    }
                    if (companyAttachMap.containsKey(company.getBankAccountCertificateFile())) {
                        company.setBankAccountCertificateFileName(companyAttachMap.get(company.getBankAccountCertificateFile()).getDisplayName());
                    }
                });
        return OutputData.builder()
                .qResponse(response)
                .build();
    }

    @Getter
    @Setter
    @Builder
    public static class InputData extends AbstractUseCase.InputData {

        @NotNull(message = "用户ID不能为空")
        private Long userId;

        private QRequest request;

        private QPage requestPage;
    }

    @Getter
    @Setter
    @Builder
    public static class OutputData extends AbstractUseCase.OutputData {
        private QResponse<HousekeepingCompany> qResponse;
    }
}
